#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include "tree.h"


const int MAX_BOXES_NUMBER = 1000;
const int MAX_STRING_SIZE  = 1000;
const int MAX_COMMAND_SIZE = 20;
const int MAX_SYMBOL_SIZE  = 20;

char input[MAX_STRING_SIZE] = {};
int pointer = 0;

//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------



void number_analysis(int* box_step , info_tree* boxes);
void string_analysis(int* box_step , info_tree* boxes);
void symbol_analysis(int* box_step , info_tree* boxes);

int check_symbol(char symbol);
void print_boxes(info_tree* boxes);

void Lexical_analysis(info_tree* boxes);

void Lexical_analysis(info_tree* boxes)
{

    assert(boxes);

    int box_step = 0;
    int length = strlen(input);

    while(pointer < length)
    {

//        printf("\n\nok\n");

        if(isspace(input[pointer]))
        {
            pointer++;
        }

        else if('a' <= input[pointer] && input[pointer] <= 'z')
        {

            string_analysis(&box_step , boxes);

        }


        else if('0' <= input[pointer] && input[pointer] <= '9')
        {

            number_analysis(&box_step , boxes);

        }

        else if(check_symbol(input[pointer]))
        {

            symbol_analysis(&box_step , boxes);

        }
        else
        {
            printf("mamu ebal '%c'\n", input[pointer]);
            assert(!"Nsdfsdfs");
        }


    }

    print_boxes(boxes);

}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void print_boxes(info_tree* boxes)
{
    assert(boxes);

    int step = 0;

    while(boxes[step].flag != 0)
    {

        printf("box number %d content : flag %d , if est box content box_value %d\n" , step , boxes[step].flag , boxes[step].value);

        step++;

    }

}

void symbol_analysis(int* box_step , info_tree* boxes)
{

    assert(boxes);

    int step = 0;

    char symbol_conn[MAX_SYMBOL_SIZE] = {};

    while(check_symbol(input[pointer]))
    {

        symbol_conn[step] = input[pointer];
        pointer++;

        step++;
    }

    #define EQUAL(name , str , number_type) if(strcmp(symbol_conn , str) == 0) { info_tree INFO = {}; INFO.flag = number_type; boxes[*box_step]  = INFO; }
    #include "TYPES.h"
    #undef  EQUAL(name , str , number_type)

    (*box_step)++;

}

int check_symbol(char symbol)
{
    if((symbol == ';') || (symbol == '*') || (symbol == '^') || (symbol == '+') || (symbol == '(') || (symbol == ')')|| (symbol == '=') || (symbol == '<')
    || (symbol == '>') || (symbol == '&') || (symbol == '|') || (symbol == '/') || (symbol == '-') || (symbol == '{') || (symbol == '}')) { return 1; }

    return 0;
}

void string_analysis(int* box_step , info_tree* boxes)
{

    assert(box_step);
    assert(boxes);

    info_tree INFO = {};

    int step = 0;
    char command[MAX_COMMAND_SIZE] = {};

    while('a' <= input[pointer] && input[pointer]<= 'z')
    {

        command[step] = input[pointer];
        step++;

        pointer++;

    }

    if(0) { }

    #define EQUAL(name , str , number_type) else if(strcmp(command , str) == 0) { INFO.flag = number_type; }
    #include "TYPES.h"
    #undef  EQUAL(name , str , number_type)

    else
    {

        INFO.flag = VAR_TYPE;
        strcpy(INFO.var , command);

    }

    boxes[*box_step] = INFO;
    (*box_step)++;

}

void number_analysis(int* box_step , info_tree* boxes)
{

    assert(box_step);
    assert(boxes);

    info_tree INFO = {};
    int value = 0;

    while('0' <= input[pointer] && input[pointer] <= '9')
    {

        if(input[pointer] == '\0') {break;}

        value = 10*value + input[pointer] - '0';
        pointer++;

    }

    INFO.value = value;
    INFO.flag  = CHISLO_TYPE;

    boxes[*box_step] = INFO;
    (*box_step)++;

}
